package com.keldor.dao;


import org.hibernate.sql.Update;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import com.keldor.model.Articulo;
import com.keldor.model.Familia;
import com.keldor.model.Historial;

@Service
public class ArticuloDAOMySQLImpl extends JdbcDaoSupport  implements ArticuloDAO{

	
	@Autowired
	  public ArticuloDAOMySQLImpl(DataSource dataSource) {
	    setDataSource(dataSource);
	  }

	public List<Familia> getFamilias() {
		  //String SQL = "select DISTINCT r.cod_familia from RELACION_FAMILIA r where r.cod_familia NOT IN(select cod_subfamilia from relacion_familia);";
		String SQL = "select * from FAMILIA where nodo='raiz'";
		List <Familia> familias = getJdbcTemplate().query(SQL, new FamiliaMapper());
	      return familias;
		
	}
	
	public Familia getFamilia(int cod_familia) {
		  //String SQL = "select DISTINCT r.cod_familia from RELACION_FAMILIA r where r.cod_familia NOT IN(select cod_subfamilia from relacion_familia);";
		String SQL = "select * from FAMILIA where cod_familia=?";
		List <Familia> familias = getJdbcTemplate().query(SQL,new Object[]{cod_familia}, new FamiliaMapper());
		if (familias.size()>0) {
			return familias.get(0);
		} else {
			return null;
		}
		
	}
	

	public List<Articulo> getArticulos(int cod_familia, int cod_subfamilia) {
		  String SQL = "select a.* from ARTICULO a inner join SUBFAMILIA s on s.cod_subfamilia=a.cod_subfamilia "+
				  	   		"inner join FAMILIA f on f.cod_familia=a.cod_familia "+
				  	   		"where a.cod_familia=? and a.cod_subfamilia=?";
	      List <Articulo> articulos = getJdbcTemplate().query(SQL, new Object[]{cod_familia,cod_subfamilia}, new ArticuloMapper());
	      return articulos;
	}
	
	public List<Articulo> getArticulos(int cod_subfamilia) {
		  String SQL = "select a.* from ARTICULO a, RELACION_ARTICULO_FAMILIA f where f.cod_articulo=a.cod_articulo and f.cod_familia=?";
	      List <Articulo> articulos = getJdbcTemplate().query(SQL, new Object[]{cod_subfamilia}, new ArticuloMapper());
	      return articulos;
	}

	public List<Familia> getSubFamilias(int cod_familia) {
		  String SQL = "select f.* from RELACION_FAMILIA r, FAMILIA f where f.cod_familia=r.cod_subfamilia and r.cod_familia=? GROUP BY f.cod_familia";
	      List <Familia> subfamilias = getJdbcTemplate().query(SQL, new Object[]{cod_familia}, new FamiliaMapper());
	      return subfamilias;
	}
	
	public List<Familia> getMismaSubFamilias(int cod_subfamilia) {
		  String SQL = "select s.* from FAMILIA s, RELACION_FAMILIA r where r.cod_subfamilia=s.cod_familia and r.cod_familia="+
				  		"(select re.cod_familia from RELACION_FAMILIA re where re.cod_subfamilia=?)";
	      List <Familia> subfamilias = getJdbcTemplate().query(SQL, new Object[]{cod_subfamilia}, new FamiliaMapper());
	      return subfamilias;
	}

	public void setCarritoHistorial(List<Historial> historial) {
		
		for (int i = 0; i < historial.size(); i++) {
			String SQL = "insert into Historial (fecha, id_usuario, cod_articulo, cantidad, tipo_movimiento) values (now(), ?, ?, ?, ?)";
		    getJdbcTemplate().update( SQL, historial.get(i).getId_usuario(), historial.get(i).getCod_articulo(), historial.get(i).getCantidad(), historial.get(i).getTipo_movimiento());
		}
	    return;
		
	}

	public void actualizarStock(int id_articulo, int cantidad) {
		
			String SQL = "update articulo SET stock=(stock+?) where cod_articulo=?";
			getJdbcTemplate().update( SQL, cantidad, id_articulo);
		return;
	}

	public boolean tieneArticulos(int cod_familia) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean tieneSubFamilias(int cod_familia) {
		//Se comprueba si es una subfamilia final
		  String SQL = "select cod_subfamilia from relacion_familia where cod_familia=?";
	      List<Integer> id_subFamiliasFinales = getJdbcTemplate().queryForList(SQL, new Object[]{cod_familia}, Integer.class);
	      if (id_subFamiliasFinales.size()>0) {
			return true;
		} else {
			return false;
		}
	}
	
	public int getIdFamiliaPadre(int cod_subFamilia){
		String SQL = "select f.cod_familia from RELACION_FAMILIA r, FAMILIA f where r.cod_subfamilia=? and r.cod_familia=f.cod_familia GROUP BY f.cod_familia";
		List<Integer> id_familiaPadre = getJdbcTemplate().queryForList(SQL, new Object[]{cod_subFamilia}, Integer.class);
		
		if (id_familiaPadre.size()>0) {
			String SQL2 = "select f.cod_familia from RELACION_FAMILIA r, FAMILIA f where r.cod_subfamilia=? and r.cod_familia=f.cod_familia GROUP BY f.cod_familia";
			List<Integer> is_raiz = getJdbcTemplate().queryForList(SQL2, new Object[]{id_familiaPadre.get(0)}, Integer.class);
			if (is_raiz.size()>0) {
				return id_familiaPadre.get(0);
			} else{
				return -1;
			}
		} else {
			return -1;
		}
	}

	
	public int getStockArticulo(int cod_articulo) {
		String SQL = "select stock from ARTICULO where cod_articulo=?";
		Object[] params = new Object[] { cod_articulo};
		return getJdbcTemplate().queryForObject(SQL, params, Integer.class);
	}

	public Articulo getArticulo(int cod_articulo) {
		String SQL = "select * from ARTICULO where cod_articulo=?";
		Object[] params = new Object[] { cod_articulo};		
		return	getJdbcTemplate().queryForObject(SQL, params,new ArticuloMapper());
	}

	public int getStockTotal() {
		String SQL = "select sum(stock) from ARTICULO";
		return getJdbcTemplate().queryForObject(SQL, Integer.class);
	}

	public float getValorTotal() {
		String SQL = "select sum(stock*precio) from ARTICULO";
		return getJdbcTemplate().queryForObject(SQL, Float.class);
	}

	public int getStockFamilia(int cod_familia) {
		List<Familia> familias = getSubFamilias(cod_familia);
		if(familias.size()==0){
			familias.add(getFamilia(cod_familia));
		}
		int sum=0;
		
		return getStock(sum,familias);
	}
	
	public int getStock(int sum, List<Familia> familias){
		for (int i = 0; i < familias.size(); i++) {
			if(familias.get(i).getNodo().equals("final")){
				String SQL = "select SUM(a.stock) from ARTICULO a, RELACION_ARTICULO_FAMILIA r where a.cod_articulo=r.cod_articulo and r.cod_familia=?";
				Object[] params = new Object[] { familias.get(i).getCod_familia()};	
				Object res = getJdbcTemplate().queryForObject(SQL, params, Integer.class);
				if(res!=null){
					return sum += Integer.parseInt(res.toString());
				}
			} else {
				List<Familia> familias2 = getSubFamilias( familias.get(i).getCod_familia());
				sum = getStock(sum, familias2);
			}
		}
		return sum;
	}
	
	public float getValor(float sum, List<Familia> familias){
		for (int i = 0; i < familias.size(); i++) {
			if(familias.get(i).getNodo().equals("final")){
				String SQL = "select SUM(a.stock*a.precio) from ARTICULO a, RELACION_ARTICULO_FAMILIA r where a.cod_articulo=r.cod_articulo and r.cod_familia=?";
				Object[] params = new Object[] { familias.get(i).getCod_familia()};	
				Object res = getJdbcTemplate().queryForObject(SQL, params, Float.class);
				if(res!=null){
					return sum += Float.parseFloat(res.toString());
				}
			} else {
				List<Familia> familias2 = getSubFamilias( familias.get(i).getCod_familia());
				sum = getValor(sum, familias2);
			}
		}
		return sum;
	}

	public float getValorFamilia(int cod_familia) {
		List<Familia> familias = getSubFamilias(cod_familia);
		if(familias.size()==0){
			familias.add(getFamilia(cod_familia));
		}
		float sum=0;
		return getValor(sum,familias);
	}

	public Articulo actualizarArticulo(Articulo articulo) {
		String SQL = "UPDATE articulo SET precio=?, stock=? WHERE cod_articulo=?";
		Object[] params = new Object[] { articulo.getPrecio(), articulo.getStock(), articulo.getCod_articulo()};	
		getJdbcTemplate().update(SQL, params);
		return articulo;
	}

	public Articulo nuevoArticulo(Articulo articulo) {
		String SQL = "INSERT into ARTICULO (nombre, precio, stock, id_almacen) values (?,?,?,?)";
		Object[] params = new Object[] { articulo.getNombre(), articulo.getPrecio(), articulo.getStock(), articulo.getId_almacen()};
		getJdbcTemplate().update(SQL, params);
		String SQL2 = "select * from ARTICULO where nombre=?";
		Object[] params2 = new Object[] { articulo.getNombre()};
		return getJdbcTemplate().queryForObject(SQL2, params2, new ArticuloMapper());
		
	}
	
	public void nuevaRelFamiliaArticulo(int cod_articulo, int cod_familia) {
		String SQL = "INSERT into RELACION_ARTICULO_FAMILIA (cod_articulo, cod_familia) values (?,?)";
		Object[] params = new Object[] { cod_articulo, cod_familia};
		getJdbcTemplate().update(SQL, params);
	}
	
	

	public List<Familia> getFamiliasFinal() {
		String SQL = "select * from FAMILIA where nodo='final'";
		List <Familia> familias = getJdbcTemplate().query(SQL, new FamiliaMapper());
	      return familias;
	}

	public Articulo getArticuloNombre(String nombre) {
		String SQL2 = "select * from ARTICULO where nombre=?";
		Object[] params2 = new Object[] { nombre};
		return getJdbcTemplate().queryForObject(SQL2, params2, new ArticuloMapper());
	}
	
	public boolean existArticuloNombre(String nombre) {
		String SQL = "select * from ARTICULO where nombre=?";
		Object[] params = new Object[] { nombre};
		List <Articulo> articulos = getJdbcTemplate().query(SQL, params, new ArticuloMapper());
		if(articulos.size()>0){
			return true;
		} else{
			return false;
		}
	}

	

}
